// 请求
package controller

import (
	"goHelpers/app/constant"
	"strconv"

	bootEntity "gitee.com/copylian/lian-go.git/entity"
	jwtHelper "gitee.com/copylian/lian-go.git/helper/jwt"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

// Request 请求结构体
type Request struct {
	GCtx *gin.Context
	Val  string
}

// NewRequest 请求方法
func NewRequest(ctx *gin.Context) Request {
	return Request{GCtx: ctx}
}

// GetHeader 获取响应头
func (req Request) GetHeader(key string) Request {
	req.Val = req.GCtx.GetHeader(key)
	return req
}

// GetQuery 获取问号请求参数
func (req Request) GetQuery(key string) Request {
	req.Val = req.GCtx.Query(key)
	return req
}

// GetQueryDefault 获取问号请求参数，有默认值
func (req Request) GetQueryDefault(key, defaultValue string) Request {
	req.Val = req.GCtx.DefaultQuery(key, defaultValue)
	return req
}

// PostForm 获取POST请求参数
func (req Request) PostForm(key string) Request {
	req.Val = req.GCtx.PostForm(key)
	return req
}

// PostFormDefault 获取POST请求参数，有默认值
func (req Request) PostFormDefault(key, defaultValue string) Request {
	req.Val = req.GCtx.DefaultPostForm(key, defaultValue)
	return req
}

// ShouldBindQuery 绑定参数到结构体
//
//	type UserInfo struct {
//		Name string `form:"name"`
//		Sex  int    `form:"sex"`
//	}
//
// var userInfo UserInfo
// c.ShouldBindQuery(&userInfo)
func (req Request) ShouldBindQuery(obj any) {
	_ = req.GCtx.ShouldBindQuery(obj)
}

// ShouldBindJSON 绑定Json结构体数据
//
//	type UserInfo struct {
//		Name string `json:"name"`
//		Sex  int    `json:"sex"`
//	}
//
// var userInfo UserInfo
// c.ShouldBindJSON(&userInfo)
func (req Request) ShouldBindJSON(obj any) {
	_ = req.GCtx.ShouldBindJSON(obj)
}

// IsMimeJson 判断是否是json类型
func (req Request) IsMimeJson() bool {
	return req.GCtx.ContentType() == binding.MIMEJSON
}

// PostToModel post绑定到结构体
func (req Request) PostToModel(obj any) Request {
	if req.IsMimeJson() {
		_ = req.GCtx.ShouldBindBodyWith(obj, binding.JSON)
	} else {
		_ = req.GCtx.ShouldBind(obj)
	}
	return req
}

// GetAllParamsFromUrl 获取url中所有参数, 不支持数组
func (req Request) GetAllParamsFromUrl() map[string]string {
	reqParams := make(map[string]string)
	params := req.GCtx.Request.URL.Query()
	for key, value := range params {
		if len(value) == 1 {
			reqParams[key] = value[0]
		}
	}
	return reqParams
}

// GetUserIdByToken 通过token获取user_id
func (req Request) GetUserIdByToken() uint32 {
	// 获取token
	token := req.GetHeader("token").Val
	if token == "" {
		return 0
	}
	// 本地解析jwt
	jwtInfo, err := jwtHelper.ParseToken(token, &bootEntity.JwtConfig{JwtSecret: constant.JwtSecret, JwtTTL: constant.JwtTTL})
	if err != nil || jwtInfo == nil || len(jwtInfo.Data) == 0 {
		return 0
	}

	// 处理user_id
	var userId float64
	if val, ok := jwtInfo.Data["user_id"]; ok && val != nil {
		// 断言
		userId, _ = val.(float64)
	}
	return uint32(userId)
}

// GetUserId2 获取user_id
func (req Request) GetUserId() uint32 {
	var userId float64
	if val, ok := req.GCtx.Get("user_id"); ok && val != nil {
		// 断言
		userId, _ = val.(float64)
	}
	return uint32(userId)
}

// Uint32 值转uint32
func (req Request) Uint32() uint32 {
	val, _ := strconv.ParseInt(req.Val, 10, 32)
	return uint32(val)
}

// Int 值转uint32
func (req Request) Int() int {
	val, _ := strconv.ParseInt(req.Val, 10, 32)
	return int(val)
}

// Uint 值转uint
func (req Request) Uint() uint {
	val, _ := strconv.ParseUint(req.Val, 10, 32)
	return uint(val)
}

// Bool 值转bool
func (req Request) Bool() bool {
	b, _ := strconv.ParseBool(req.Val)
	return b
}

// Value 获取值
func (req Request) Value() string {
	return req.Val
}
